<?php

namespace IYUU\sdk\CoolQ\Domain;

use BadRequestException;
use IYUU\sdk\CoolQ\Context;
use IYUU\sdk\CoolQ\CoolQCode;
use IYUU\sdk\CoolQ\Event\Message as EventMessage;
use Psr\SimpleCache\InvalidArgumentException;
use Throwable;

/**
 * 群聊消息处理器
 * Class MessageGroup
 * @package IYUU\sdk\CoolQ\Domain
 */
class MessageGroup
{
    /**
     * 应答方法
     * @param Context $context
     * @param EventMessage $msgObj
     * @return array
     * @throws BadRequestException
     */
    public static function respond(Context $context, EventMessage $msgObj): array
    {
        $message = $context->get('message', '');
        $user_id = $context->get('user_id', 0);
        /**
         * 系统功能：违禁词检查
         */
        if (!in_array($context->get('group_id', 0), $msgObj->getConfig('repetition.allow.group_id', []))) {
            // 1. 检查敏感词
            $result = BannedWords::check($message);
            if ($result) {
                $resp = sprintf('您的发言包含敏感词【%s】，RID:%d', $result['content'], $result['id']);
                return EventMessage::replyGroup($resp, false, true, true, false, true, 60);
            }

            // 2. 检查关键字：打卡、签到，处理结果：撤回
            if (($message === '打卡') || ($message === '签到')) {
                // 撤回消息
                //getOneBot()->deleteMsg($context->get('message_id'));
            }
        }

        /**
         * 系统功能：黑名单检查
         */
        $resp = BlackList::check($user_id);
        if (!empty($resp)) {
            // 检测到QQ存在于黑名单中【处理结果：AT、踢出群聊、禁言1天】
            return EventMessage::replyGroup($user_id . ' QQ在黑名单', false, true, false, true, true, 86400);
        }

        /**
         * 系统功能：群消息刷屏检测与复读
         */
        /*$resp = static::repeat($context, $msgObj);
        if (!empty($resp)) {
            return $resp;
        }*/

        /**
         * 功能：发送获取Cookie方法的图片
         * 触发方法：$message包含cookie
         */
        if (stripos($message, 'cookie') !== false) {
            return EventMessage::replyGroup(CoolQCode::Image('https://iyuu-1251099245.file.myqcloud.com/usr/uploads/2021/08/711763021.png'), false, true);
        }

        return [];
    }

    /**
     * 功能：管理群消息复读
     * @param Context $context
     * @param EventMessage $msgObj
     * @return array
     * @throws BadRequestException
     * @throws InvalidArgumentException
     */
    private static function repeat(Context $context, EventMessage $msgObj): array
    {
        // 取配置
        $repetition = $msgObj->getConfig('repetition');
        $forbid = $repetition['forbid'] ?? [];
        $allow = $repetition['allow'] ?? [];

        $message = $context->get('message', '');
        $self_id = $context->get('self_id', 0);
        $group_id = $context->get('group_id', 0);
        try {
            // 缓存KEY
            $cache_key = static::getContextCacheKeyGroupMessage($message, $self_id, $group_id);

            /**
             * 判断群ID是否禁止复读
             */
            if (in_array($group_id, $forbid['group_id'] ?? [])) {
                $exclude = $forbid['message_exclude'] ?? [];// 排除关键字
                $ttl = $forbid['message_ttl'] ?? 60;     // 消息TTL
                $count = $forbid['message_count'] ?? 3;    // 消息的第N句
                $ban_duration = $forbid['ban_duration'] ?? 1;   // 禁言时长

                // 1.判断排除关键字
                if (empty($exclude) || in_array($message, $exclude)) {
                    return [];
                }

                // 2.缓存计数累加
                $cache_count = Context::incCache($cache_key, $ttl);

                // 3.第N句才撤回消息
                $msg = '本群禁止复读：同样的消息' . $ttl . '秒内，不允许重复发送。';
                if ($cache_count < $count) {
                    // 未达阈值
                    return [];
                } elseif ($cache_count === $count) {
                    // 等于阈值(撤回消息)
                    //return EventMessage::replyGroup($msg, false, true, true);
                } else {
                    // 大于阈值(撤回消息，并禁言，禁言时间递增)
                    $inc = $cache_count - $count;   // 违规大于阈值几次啦？
                    $ban_duration += ($inc > $count ? $inc * $cache_count : $inc);
                    return EventMessage::replyGroup($msg, false, true, true, false, true, $ban_duration * 60);
                }
            }

            /**
             * 判断群ID是否允许复读
             */
            if (in_array($group_id, $allow['group_id'] ?? [])) {
                $exclude = $allow['message_exclude'] ?? [];// 排除关键字
                $ttl = $allow['message_ttl'] ?? 60;     // 消息TTL
                $count = $allow['message_count'] ?? 5;    // 消息的第N句
                // 1.判断排除关键字
                if (empty($exclude) || in_array($message, $exclude)) {
                    return [];
                }

                // 2.缓存计数累加
                $cache_count = Context::incCache($cache_key, $ttl);

                // 3.第N句才复读
                return ($cache_count === $count) ? EventMessage::reply($message, false) : [];
            }
        } catch (Throwable $ex) {
            // 缓存出错啦，通知主人
            $msgObj->sendMaster(__METHOD__ . ' 出现异常，请检查Redis缓存！');
            throw new BadRequestException($ex->getMessage(), $ex->getCode());
        }
        return [];
    }

    /**
     * 获取群聊消息的缓存key
     * @param string $message
     * @param int $self_id
     * @param int $group_id
     * @return string
     */
    public static function getContextCacheKeyGroupMessage(string $message, int $self_id, int $group_id): string
    {
        $replace = [
            '{self_id}' => $self_id,
            '{group_id}' => $group_id,
            '{hash}' => sha1($message)
        ];
        return strtr(Context::CacheKeyGroupMessage, $replace);
    }
}
